#!/usr/bin/env python2

# Copyright (C) Benjamin Vanheuverzwijn 2011

import getopt
import sys
import serial
import struct
import random
import Queue
import time

from PyQt4 import QtGui
from PyQt4 import QtCore
from xbee import XBee


#
# Global data
#
send_queue = Queue.LifoQueue()

#
# Borne class application
#
class Borne_Application:
    def __init__(self):
        random.seed(241)

    def printUsage(self):
        print("""\
borne-qt - version 0.1
This application broadcast over XBee the cursor position

Usage:

Options:
  -p, --path        XBee path (default: /dev/ttyUSB0)
  -b, --baudrate    XBee baudrate (default: 9600)
  -h, --help        Print this text then exit.
    """)

    def runGui(self):
        app = QtGui.QApplication(sys.argv)
        window = Borne_MainWindow()

        window.show()
    
        return app.exec_()

#
# Main Window class that cath up the mouse position
#
class Borne_MainWindow(QtGui.QMainWindow):
    def __init__(self, win_parent=None):
        QtGui.QMainWindow.__init__(self, win_parent)

        self.initWidgets()

        self.worker = Borne_XBeeThread()
        self.worker.start()

        #screensaver = Borne_Screensaver()
        #screensaver.matrix()

    # INIT
    def initWidgets(self):
        self.central_widget = QtGui.QWidget()

        self.setCentralWidget(self.central_widget)
        self.setWindowTitle("Borne interactive")
        self.resize(640,480)
        
    # EVENTS
    def mouseMoveEvent(self, event):
        global send_queue

        led = Borne_Led(event.pos().x() * 16 / 640, event.pos().y() * 8 / 480, random.randint(1,7))

        send_queue.put(led)

        print "event: " + str(event.pos().x()) + ", " + str(event.pos().y())
        print "sent to queue: " + str(led.x) + ", " + str(led.y)

#
# XBee send worker
#
class Borne_XBeeThread(QtCore.QThread):
    def __init__(self, parent = None):
        QtCore.QThread.__init__(self, parent)
        self.initXbee("/dev/ttyUSB0", 9600)
        self.alive = 1
        # tortue id : 0x5678
        self.tortue_id = "\x56\x78"

    def initXbee(self, path, baudrate):
        self.ser = serial.Serial(path, baudrate)
        self.xbee = XBee(self.ser)

    def run(self):
        global send_queue

        while self.alive:
            led = send_queue.get()

            if led.x >= 0 and led.x <= 255 and led.y >= 0 and led.y <= 255:
                self.xbee.tx(dest_addr=self.tortue_id, frame_id="\x00", data=struct.pack("!BBB", led.x, led.y, led.color))

            self.msleep(25)

    def stop(self):
        self.alive = 0

#
# Beautiful screensaver
#
class Borne_Screensaver():
    # Matrix (classic!)
    def matrix(self):
        global send_queue

        while True:
            column = random.randint(1,16)

            for i in range(0,random.randint(3,8)):
                led = Borne_Led(column, i, Borne_Led.GREEN)
                send_queue.put(led)
                time.sleep(0.085)

    # Draw a fish
    def fish(self):
        while True:
            meh = 0

    # Random flashing shit
    def random(self):
        while True:
            meh = 0

#
# Led structure (must match arduino's one)
#
class Borne_Led():
    BLUE = 1
    GREEN = 2
    RED = 4

    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color

#
# Main
#
if __name__ == "__main__":

    application = Borne_Application()

    try:
        opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
    except getopt.GetoptError:
        application.printUsage()
        sys.exit(1)

    for option, arg in opts:
        if option in ("-h", "--help"):
            application.printUsage()
            sys.exit()

    if not args:
        sys.exit(application.runGui())
